using Autofac;
using Autofac.Extensions.DependencyInjection;
using EFCore;
using FluentScheduler;
using FreeSql;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using MyDapper;
using MyFreeSql;
using MyMongoDB;
using MyRedis;
using MySqlSugar;
using MySqlSugar.Context;
using QuickCode.Application;
using QuickCode.Application.DTO.Config;
using QuickCode.IApplication;
using QuickCode.WebApi;
using System.Text;
using Until.Helper;
using Until.Model;
//------------------------------------------------------------------------------------应用创建器------------------------------------------------------------------------------------
var sqlstr = ConfigurationHelper.GetValue("Environment:DBSetting:ConnectStr");
var dBType = ConfigurationHelper.GetValue("Environment:DBSetting:Type");
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

#region Swagger配置
//配置Swagger
builder.Services.AddSwaggerGen(s =>
{
    s.SwaggerDoc("Authorize", new OpenApiInfo { Version = "Authorize", Title = "鉴权" });
    s.SwaggerDoc("User", new OpenApiInfo { Version = "User", Title = "用户基础接口" });
    s.DocInclusionPredicate((d, a) => a.GroupName.ToUpper() == d.ToUpper());
    string b = Path.GetDirectoryName(typeof(Program).Assembly.Location);
    s.IncludeXmlComments(Path.Combine(b, "API.xml"));
    //s.IncludeXmlComments(Path.Combine(d, "DTO.xml"));
    s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    {
        Description = "在下框中输入请求头中需要添加Jwt授权Token：Bearer Token",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
    s.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
});
#endregion

#region 跨域信息配置
//配置跨域信息
builder.Services.AddCors(options =>
{
    options.AddPolicy("Any",
    policy => policy.AllowAnyHeader().WithExposedHeaders("Content-Disposition")
    .WithMethods("GET","POST","PUT","DELETE","HEAD","OPTIONS")//.AllowAnyMethod()  允许所有请求方式
    .AllowAnyOrigin());
});
#endregion

#region EF-Core注入
builder.Services.AddDbContext<MyDB>();
#endregion

#region Dapper仓储注入
builder.Services.AddScoped(typeof(IDapperRepository), typeof(DapperRepository));
#endregion

#region SQL Sugar 注入
#region SQL Sugar仓储注入
builder.Services.AddScoped(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>));
#endregion
builder.Services.AddSingleton(sp => new SqlSugarContext(
    new SqlSugar.SqlSugarClient(new SqlSugar.ConnectionConfig()
    {
        ConnectionString = sqlstr,//数据库连接串
        DbType = dBType == "SqlServer" ? SqlSugar.DbType.MySql : SqlSugar.DbType.MySql,//数据库类型
        IsAutoCloseConnection = true //自动释放
    })
));
#endregion

#region FreeSql注入
var dataTypeEnum = dBType == "SqlServer" ? DataType.SqlServer : DataType.MySql;//1:SqlServer;0:MySql
IFreeSql fsql = new FreeSqlBuilder()
               .UseConnectionString(dataTypeEnum, sqlstr) //可以写入json文件
               .UseAutoSyncStructure(true) //自动同步实体结构到数据库，FreeSql不会扫描程序集，只有CRUD时才会生成表。
               .Build(); //请务必定义成 Singleton 单例模式
builder.Services.AddSingleton(fsql);
builder.Services.AddScoped<UnitOfWorkManager>();
builder.Services.AddFreeRepository(null);
#region freesql泛型仓储注入
//泛型仓储
builder.Services.AddScoped(typeof(IFreesqlRepository<>), typeof(FreesqlRepository<>));
#endregion
#endregion FreeSql

#region AutoMapper注入
builder.Services.AddAutoMapper(typeof(AutoMapperConf));
#endregion

#region 批量依赖注入

#region 一、AutoFac注入
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.RegisterModule(new AutofacModuleRegister());
});
#endregion

#region 二、自带批量注入
//builder.Services.AddScoped(Assembly.Load("QuickCode.IApplication"), Assembly.Load("QuickCode.Application"));
#endregion

#endregion

#region JWT配置
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true,
        ValidIssuer = builder.Configuration["Logging:tokenManagement:issuer"],
        ValidateAudience = true,
        ValidAudience = builder.Configuration["Logging:tokenManagement:audience"],
        ValidateLifetime = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Logging:tokenManagement:secret"]))
    };
    options.Events = new JwtBearerEvents
    {
        OnChallenge = context =>
        {
            //此处代码为终止.Net Core默认的返回类型和数据结果，这个很重要哦，必须
            context.HandleResponse();
            var payload = "{\"code\":401,\"err\":\"无登录信息或登录信息已失效，请重新登录。\"}";
            //自定义返回的数据类型
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = StatusCodes.Status200OK;
            context.Response.WriteAsync(payload);
            return Task.FromResult(0);
        }
    };
});
#endregion

#region Redis注入
builder.Services.AddSingleton<IRedisManage, RedisManage>();
#endregion

#region AppHelper注入
builder.Services.AddSingleton(new AppHelper(builder.Configuration));
#endregion

#region MongoDB注入
//Mongo仅支持Windows10及Windows2016以后的服务器
//builder.Services.AddSingleton<IMongoDBManage, MongoDBManage>();
#endregion

//builder.Services.AddScoped<HelloWorldApplication>();

//-----------------------------------------------------------------------------------创建应用并启动-----------------------------------------------------------------------------------
var app = builder.Build();

#region
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
//    app.UseSwagger();
//    app.UseSwaggerUI(s =>
//    {
//        s.SwaggerEndpoint("/swagger/Authorize/swagger.json", "Authorize");
//        s.SwaggerEndpoint("/swagger/User/swagger.json", "User");
//        s.EnableFilter();
//    });
//}

#endregion

app.UseSwagger();
app.UseSwaggerUI(s =>
{
    s.SwaggerEndpoint("/swagger/Authorize/swagger.json", "Authorize");
    s.SwaggerEndpoint("/swagger/User/swagger.json", "User");
    s.EnableFilter();
});

app.UseHttpsRedirection();

app.UseAuthentication();//启用jwt认证 一定要在权限启用前面

app.UseAuthorization();//权限

app.UseCors("Any");//启用跨域

app.MapControllers();

JobManager.Initialize(new FluentSchedulerFactory());

app.Run();
